home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / extend5.zip / EXTEND.PAS < prev    next >
Pascal/Delphi Source File  |  1990-11-19  |  5KB  |  124 lines

  1. {$I-,O-,R-}
  2.  
  3. unit Extend;
  4.  
  5. { This unit allows a program to open more than the standard DOS maximum of 20
  6.   open files at one time.  You must also be sure to set a FILES=XX statement
  7.   in your CONFIG.SYS file.  This program installs a special interrupt handler
  8.   under DOS 2.x, some semi-documented features under DOS 3.x prior to
  9.   DOS 3.3 and the DOS extend files call under DOS 3.3 or later.  This
  10.   unit USES the DOS unit and should be used before any other units other than
  11.   the DOS unit.  This code was based upon earlier work by Randy Forgaard, Bela
  12.   Lubkin and Kim Kokkonen.  See EXTEND.DOC for more information.
  13.  
  14.   Scott Bussinger
  15.   Professional Practice Systems
  16.   110 South 131st Street
  17.   Tacoma, WA  98444
  18.   (206)531-8944
  19.   Compuserve [72247,2671] }
  20.  
  21. { ** Revision History **
  22.   1 EXTEND.PAS 9-Mar-89,`SCOTT' First version using TLIB -- Based on 3.2
  23.   2 EXTEND.PAS 15-Sep-89,`SCOTT'
  24.            Added SwapVectorsExtend procedure
  25.            Put handle table into DOS memory
  26.            Use DOS 3.3 extended handles function when available
  27.   3 EXTEND.PAS 2-Oct-89,`SCOTT'
  28.            Fixed bug in determining the DOS version
  29.   4 EXTEND.PAS 5-Oct-89,`SCOTT'
  30.            Yet another bug in the DosVersion detection
  31.   5 EXTEND.PAS 19-Nov-90,`SCOTT'
  32.            New version of EXTEND that is compatible with Turbo Pascal 6.0
  33.            Modified the documentation and version numbers to be less confusing
  34.   ** Revision History ** }
  35.  
  36. interface
  37.  
  38. procedure SwapVectorsExtend;
  39.   { Swap interrupt vectors taken over by Extend unit with system vectors }
  40.  
  41. implementation
  42.  
  43. uses Dos,Shrink;
  44.  
  45. type HandleArray = array[0..254] of byte;        { Room for 255 handles }
  46.      HandleArrayPtr = ^HandleArray;
  47.  
  48. var DosMemory: pointer;                          { Pointer to memory gained from DOS }
  49.     ExitSave: pointer;                           { Previous exit procedure }
  50.     OldInt21: pointer;                           { Save old INT 21 }
  51.     OldHandleTable: HandleArrayPtr;              { Pointer to original table }
  52.     OldNumHandles: byte;                         { Original number of handles }
  53.  
  54. {$L EXTEND }
  55. procedure ExtendInit; external;                  { Initialize interrupt handler }
  56. procedure ExtendHandler; external;               { Replacement INT 21 handler }
  57.  
  58. procedure SwapVectorsExtend;
  59.   { Swap interrupt vectors taken over by Extend unit with system vectors }
  60.   var TempVector: pointer;
  61.   begin
  62.   if lo(DosVersion) = 2 then
  63.     begin
  64.     GetIntVec($21,TempVector);                   { Swap the INT 21 vectors }
  65.     SetIntVec($21,OldInt21);
  66.     OldInt21 := TempVector
  67.     end
  68.   end;
  69.  
  70. procedure ExtendHandles;
  71.   { Install the extended handles interrupt.  No files (other than
  72.     standard handles) should be open when unit starts up. }
  73.   var Regs: Registers;
  74.   begin
  75.   if lo(DosVersion) = 2
  76.    then
  77.     begin
  78.     GetIntVec($21,OldInt21);                     { Install interrupt handler under DOS 2.x }
  79.     ExtendInit;                                  { Initialize the interrupt handler }
  80.     SetIntVec($21,@ExtendHandler)
  81.     end
  82.    else
  83.     begin
  84.     DosNewShrink(DosMemory,sizeof(HandleArray));
  85.     if DosMemory <> nil then                     { There wasn't enough memory for a handle table, so just quit }
  86.       if (lo(DosVersion)>=4) or (hi(DosVersion)>=30) { Does this DOS version support the handles call? }
  87.        then
  88.         begin
  89.         DosDispose(DosMemory);                   { Free up the DOS memory block so that the next function will succeed }
  90.         with Regs do
  91.           begin
  92.           AH := $67;                             { Tell DOS to allow us 255 handles }
  93.           BX := 255;                             { KEEP THIS NUMBER ODD TO AVOID BUG IN SOME VERSIONS OF DOS 3.3!! }
  94.           MsDos(Regs)
  95.           end
  96.         end
  97.        else
  98.         begin
  99.         fillchar(DosMemory^,sizeof(HandleArray),$FF);     { Initialize new handles as unused }
  100.         OldNumHandles := mem[prefixseg:$0032];            { Get old table length }
  101.         OldHandleTable := pointer(ptr(prefixseg,$0034)^); { Save address of old table }
  102.         mem[prefixseg:$0032] := sizeof(HandleArray);      { Set new table length }
  103.         pointer(meml[prefixseg:$0034]) := DosMemory;      { Point to new handle table }
  104.         move(OldHandleTable^,DosMemory^,OldNumHandles)    { Copy the current handle table to the new handle table }
  105.         end
  106.     end
  107.   end;
  108.  
  109. {$F+}
  110. procedure ExitHandler;
  111. {$F-}
  112.   { Uninstall the extended handles interrupt.  All files (other
  113.     than standard handles) should be closed before unit exits. }
  114.   begin
  115.   ExitProc := ExitSave;                          { Chain to next exit routine }
  116.   SwapVectorsExtend                              { Restore original interrupt vectors }
  117.   end;
  118.  
  119. begin
  120. ExitSave := ExitProc;                            { Remember the previous exit routine }
  121. ExitProc := @ExitHandler;                        { Install our exit routine }
  122. ExtendHandles                                    { Enable the extra handles }
  123. end.
  124.